package cn.broadmax.boot.base;

import cn.broadmax.boot.base.model.LoginUser;
import cn.broadmax.boot.config.AppBaseProperties;
import cn.broadmax.boot.exception.WebException;
import cn.broadmax.boot.util.SpringContextUtils;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import jexx.io.FileUtil;
import jexx.io.IOUtil;
import jexx.poi.ExcelWriter;
import jexx.time.DateUtil;
import jexx.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.util.UriUtils;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;

/**
 * @author jeff
 * @date 2020/6/20
 */
@Slf4j
public abstract class SuperController {

    private static final String P_PAGE_NUM = "_pageNum";
    private static final String P_PAGE_SIZE = "_pageSize";

    @Autowired
    protected AppBaseProperties appBaseProperties;

    protected <T> IPage<T> getPage(int pageNum, int pageSize){
        HttpServletRequest request = SpringContextUtils.getHttpServletRequest();
        if(request == null){
            return new Page<>(1, 10);
        }

        int pn = pageNum, ps = pageSize;
        if (request.getParameter(P_PAGE_NUM) != null) {
            pn = Integer.parseInt(request.getParameter(P_PAGE_NUM));
        }
        if (request.getParameter(P_PAGE_SIZE) != null ) {
            ps = Integer.parseInt(request.getParameter(P_PAGE_SIZE));
        }

        return new Page<>(pn, ps);
    }

    protected <T> IPage<T> getPage(){
        return getPage(1, 10);
    }

    public String getAccountId() {
        LoginUser subject = SpringContextUtils.getSubject();
        if(subject == null){
            throw new WebException("认证异常");
        }
        return subject.getId();
    }

    //----------------------------------------------------------download

    /**
     * 下载文件
     * @param file 文件
     * @param response response
     */
    protected void download(File file, HttpServletResponse response){
        getFile(file, response, true, file.getName());
    }

    /**
     * 获取文件
     * @param file 文件
     * @param response response
     */
    protected void getFile(File file, HttpServletResponse response){
        getFile(file, response, false, null);
    }

    /**
     * 下载或者读取文件
     * @param file 文件
     * @param response response
     * @param isDownload 是否为下载文件
     * @param downloadFileName 下载文件的名称
     */
    protected void getFile(File file, HttpServletResponse response, boolean isDownload, String downloadFileName){
        if(!FileUtil.exists(file)){
            throw new WebException("文件不存在");
        }
        try(BufferedInputStream inputStream = FileUtil.newBufferedInputStream(file)){
            getFile(inputStream, response, isDownload, downloadFileName);
        }
        catch (IOException e){
            log.error("", e);
            throw new WebException("下载异常");
        }
    }

    /**
     * 下载或者读取文件
     * @param inputStream 数据流
     * @param response response
     * @param isDownload 是否为下载文件
     * @param downloadFileName 下载文件的名称
     */
    protected void getFile(InputStream inputStream, HttpServletResponse response, boolean isDownload, String downloadFileName){
        if(isDownload && StringUtil.isEmpty(downloadFileName)){
            throw new WebException("下载时文件名不能为空！");
        }

        ServletOutputStream servletOutputStream = null;
        try {
            if(isDownload){
                response.setContentType("application/octet-stream");
                String contentDisposition = StringUtil.format("attachment;filename={}", UriUtils.encode(downloadFileName, "UTF-8"));
                response.setHeader("Content-Disposition",contentDisposition);
            }
            response.setCharacterEncoding("UTF-8");

            servletOutputStream = response.getOutputStream();
            IOUtil.copy(inputStream, servletOutputStream);
            servletOutputStream.flush();
        }
        catch (Exception e) {
            log.error("", e);
            throw new WebException("下载失败");
        }
        finally {
            IOUtil.closeQuietly(servletOutputStream, inputStream);
        }
    }

    //----------------------------------------------------------download

    /**
     * 封装ExcelWriter的下载
     * @param file 文件
     * @param writer excel写入类
     * @param fileName 导出的文件名称
     * @param response {@link HttpServletResponse}
     */
    protected void download(File file, ExcelWriter writer, HttpServletResponse response, String fileName){
        try {
            writer.flush(file);
            getFile(file, response, true, fileName);
        }
        catch (Exception e) {
            log.error("", e);
            throw new RuntimeException(e);
        }
        finally {
            IOUtil.closeQuietly(writer);
        }
    }

    protected void download(String fileName, ExcelWriter writer, HttpServletResponse response){
        Date now = new Date();
        String lastFileName = DateUtil.format(now, "yyyyMMdd").concat("/")
                .concat(Long.toString(now.getTime())).concat("_").concat(fileName);
        File file = FileUtil.file(this.appBaseProperties.getTempDir(), lastFileName);
        try {
            FileUtil.createFileIfNotExist(file);
        } catch (IOException e) {
            e.printStackTrace();
        }
        download(file, writer, response, fileName);
    }

}
